home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Musique / Quod Libet / quodlibet-3.3.0-installer.exe / bin / quodlibet / qltk / entry.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2014-12-31  |  11KB  |  281 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. import math
  5. from gi.repository import Gtk, GObject, Gdk, Gio, Pango
  6. from quodlibet.qltk import is_accel, add_fake_accel
  7. from quodlibet.qltk.x import SeparatorMenuItem
  8.  
  9. class EditableUndo(object):
  10.     '''A simple undo/redo implementation for gtk widgets that
  11.     support the gtk.Editable interface'''
  12.     
  13.     def set_undo(self, val):
  14.         if val:
  15.             self._EditableUndo__enable_undo()
  16.         else:
  17.             self._EditableUndo__disable_undo()
  18.  
  19.     
  20.     def reset_undo(self):
  21.         self._EditableUndo__history = []
  22.         self._EditableUndo__re_history = []
  23.         self._EditableUndo__in_pos = -1
  24.         self._EditableUndo__del_pos = -1
  25.         self._EditableUndo__last_space = False
  26.  
  27.     
  28.     def undo(self):
  29.         self._EditableUndo__do(self._EditableUndo__history, self._EditableUndo__re_history)
  30.  
  31.     
  32.     def redo(self):
  33.         self._EditableUndo__do(self._EditableUndo__re_history, self._EditableUndo__history)
  34.  
  35.     
  36.     def can_undo(self):
  37.         return self._EditableUndo__can_do(self._EditableUndo__history)
  38.  
  39.     
  40.     def can_redo(self):
  41.         return self._EditableUndo__can_do(self._EditableUndo__re_history)
  42.  
  43.     
  44.     def __enable_undo(self):
  45.         self.reset_undo()
  46.         self._EditableUndo__handlers = [
  47.             self.connect('insert-text', self._EditableUndo__insert_before),
  48.             self.connect('delete-text', self._EditableUndo__delete_before),
  49.             self.connect('populate-popup', self._EditableUndo__popup),
  50.             self.connect('key-press-event', self._EditableUndo__key_press)]
  51.  
  52.     
  53.     def __key_press(self, entry, event):
  54.         if is_accel(event, '<ctrl>z'):
  55.             self.undo()
  56.             return True
  57.         if None(event, '<ctrl><shift>z'):
  58.             self.redo()
  59.             return True
  60.  
  61.     
  62.     def __disable_undo(self):
  63.         for handler in self._EditableUndo__handlers:
  64.             self.disconnect(handler)
  65.         
  66.         del self._EditableUndo__history
  67.         del self._EditableUndo__re_history
  68.         del self._EditableUndo__last_space
  69.         del self._EditableUndo__in_pos
  70.         del self._EditableUndo__del_pos
  71.  
  72.     
  73.     def __popup(self, entry, menu):
  74.         undo = Gtk.ImageMenuItem(Gtk.STOCK_UNDO, use_stock = True)
  75.         add_fake_accel(undo, '<ctrl>z')
  76.         redo = Gtk.ImageMenuItem(Gtk.STOCK_REDO, use_stock = True)
  77.         add_fake_accel(redo, '<ctrl><shift>z')
  78.         sep = SeparatorMenuItem()
  79.         for widget in [
  80.             sep,
  81.             redo,
  82.             undo]:
  83.             widget.show()
  84.         
  85.         undo.connect(('activate',), (lambda : self.undo()))
  86.         redo.connect(('activate',), (lambda : self.redo()))
  87.         undo.set_sensitive(self.can_undo())
  88.         redo.set_sensitive(self.can_redo())
  89.         for item in [
  90.             sep,
  91.             redo,
  92.             undo]:
  93.             menu.prepend(item)
  94.         
  95.  
  96.     
  97.     def __all(self):
  98.         text = self.get_chars(0, -1).decode('utf-8')
  99.         pos = self.get_position()
  100.         return [
  101.             text,
  102.             pos]
  103.  
  104.     
  105.     def __add(self):
  106.         self._EditableUndo__history.append(self._EditableUndo__all())
  107.         self._EditableUndo__re_history = []
  108.  
  109.     
  110.     def __insert_before(self, entry, text, length, position):
  111.         self._EditableUndo__del_pos = -1
  112.         pos = self.get_position()
  113.         if not pos != self._EditableUndo__in_pos:
  114.             if self._EditableUndo__last_space or text != ' ' or length > 1:
  115.                 self._EditableUndo__add()
  116.             self._EditableUndo__last_space = text == ' '
  117.             self._EditableUndo__in_pos = pos + 1
  118.             return None
  119.  
  120.     
  121.     def __delete_before(self, entry, start, end):
  122.         self._EditableUndo__in_pos = -1
  123.         text = self.get_chars(start, end)
  124.         length = end - start
  125.         pos = self.get_position()
  126.         if not pos != self._EditableUndo__del_pos:
  127.             if self._EditableUndo__last_space or text != ' ' or length > 1:
  128.                 self._EditableUndo__add()
  129.             self._EditableUndo__last_space = text == ' '
  130.             self._EditableUndo__del_pos = end - 1
  131.             return None
  132.  
  133.     
  134.     def __inhibit(self):
  135.         for handler in self._EditableUndo__handlers:
  136.             self.handler_block(handler)
  137.         
  138.  
  139.     
  140.     def __uninhibit(self):
  141.         for handler in self._EditableUndo__handlers:
  142.             self.handler_unblock(handler)
  143.         
  144.  
  145.     
  146.     def __can_do(self, source):
  147.         return bool(source)
  148.  
  149.     
  150.     def __do(self, source, target):
  151.         if not self._EditableUndo__can_do(source):
  152.             return None
  153.         self._EditableUndo__del_pos = None
  154.         self._EditableUndo__in_pos = None
  155.         self._EditableUndo__inhibit()
  156.         now = self._EditableUndo__all()
  157.         last = source.pop(-1)
  158.         if now != last:
  159.             target.append(now)
  160.         (text, pos) = last
  161.         self.delete_text(0, -1)
  162.         self.insert_text(text, 0)
  163.         self.set_position(pos)
  164.         self._EditableUndo__uninhibit()
  165.  
  166.  
  167.  
  168. class Entry(Gtk.Entry):
  169.     
  170.     def __init__(self, *args, **kwargs):
  171.         super(Entry, self).__init__(*args, **kwargs)
  172.         self._max_width_chars = -1
  173.         self.set_width_chars(5)
  174.  
  175.     
  176.     def set_max_width_chars(self, value):
  177.         '''Works with GTK+ <3.12'''
  178.         self._max_width_chars = value
  179.         self.queue_resize()
  180.  
  181.     
  182.     def do_get_preferred_width(self):
  183.         (minimum, natural) = Gtk.Entry.do_get_preferred_width(self)
  184.         if self._max_width_chars >= 0:
  185.             style_context = self.get_style_context()
  186.             border = style_context.get_border(Gtk.StateFlags.NORMAL)
  187.             padding = style_context.get_padding(Gtk.StateFlags.NORMAL)
  188.             pango_context = self.get_pango_context()
  189.             metrics = pango_context.get_metrics(pango_context.get_font_description(), pango_context.get_language())
  190.             char_width = metrics.get_approximate_char_width()
  191.             digit_width = metrics.get_approximate_digit_width()
  192.             char_pixels = int(math.ceil(float(max(char_width, digit_width)) / Pango.SCALE))
  193.             space = border.left + border.right + padding.left + padding.right
  194.             nat_width = self._max_width_chars * char_pixels + space
  195.             natural = max(nat_width, minimum)
  196.         return (minimum, natural)
  197.  
  198.  
  199.  
  200. class UndoEntry(Entry, EditableUndo):
  201.     
  202.     def __init__(self, *args):
  203.         super(UndoEntry, self).__init__(*args)
  204.         self.set_undo(True)
  205.  
  206.     
  207.     def set_text(self, *args):
  208.         super(UndoEntry, self).set_text(*args)
  209.         self.reset_undo()
  210.  
  211.  
  212.  
  213. class ClearEntryMixin(object):
  214.     '''A clear icon mixin supporting newer Gtk.Entry or
  215.     a separate clear button as a fallback.
  216.     '''
  217.     __gsignals__ = {
  218.         'clear': (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ()) }
  219.     
  220.     def enable_clear_button(self):
  221.         '''Enables the clear icon in the entry'''
  222.         gicon = Gio.ThemedIcon.new_from_names([
  223.             'edit-clear-symbolic',
  224.             'edit-clear'])
  225.         self.set_icon_from_gicon(Gtk.EntryIconPosition.SECONDARY, gicon)
  226.         self.connect('icon-release', self._ClearEntryMixin__clear)
  227.  
  228.     
  229.     def __clear(self, button, *args):
  230.         self.delete_text(0, -1)
  231.         self.emit('clear')
  232.  
  233.  
  234.  
  235. class ClearEntry(UndoEntry, ClearEntryMixin):
  236.     __gsignals__ = ClearEntryMixin.__gsignals__
  237.  
  238.  
  239. class ValidatingEntryMixin(object):
  240.     '''An entry with visual feedback as to whether it is valid or not.
  241.     The given validator function gets a string and returns True (green),
  242.     False (red), or None (black).
  243.  
  244.     parse.Query.is_valid_color mimicks the behavior of the search bar.
  245.  
  246.     If the "Color search terms" option is off, the entry will not
  247.     change color.'''
  248.     INVALID = Gdk.RGBA(0.8, 0, 0)
  249.     VALID = Gdk.RGBA(0.3, 0.6, 0.023)
  250.     
  251.     def set_validate(self, validator = None):
  252.         if validator:
  253.             self.connect('changed', self._ValidatingEntryMixin__color, validator)
  254.  
  255.     
  256.     def __color(self, widget, validator):
  257.         value = validator(self.get_text().decode('utf-8'))
  258.         if value is True:
  259.             color = self.VALID
  260.         elif value is False:
  261.             color = self.INVALID
  262.         elif value and isinstance(value, basestring):
  263.             color = Gdk.RGBA()
  264.             color.parse(value)
  265.         else:
  266.             color = None
  267.         if color and self.get_property('sensitive'):
  268.             self.override_color(Gtk.StateType.NORMAL, color)
  269.         else:
  270.             self.override_color(Gtk.StateType.NORMAL, None)
  271.  
  272.  
  273.  
  274. class ValidatingEntry(ClearEntry, ValidatingEntryMixin):
  275.     
  276.     def __init__(self, validator = None, *args):
  277.         super(ValidatingEntry, self).__init__(*args)
  278.         self.set_validate(validator)
  279.  
  280.  
  281.